"""
/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
 """
import sys
from Analyzer import SPackage, SEnum, ExField
from Analyzer import SClass
from Analyzer import SCompilationUnit
from Analyzer import SField
from Analyzer import SGlobal
from Analyzer import SHelper
from Analyzer import SInterface
from Analyzer import SMethod
from Analyzer import SModifier
from Analyzer import STypeDeclaration
from Analyzer import SAnnotationType
from JavaLangAST import Annotation, TypeParameter, ExIdentifier, ExOperator
from JavaLangAST import AnnotationMethod
from JavaLangAST import AnnotationType
from JavaLangAST import ArrayInitializer
from JavaLangAST import Block
from JavaLangAST import Class
from JavaLangAST import ClassBody
from JavaLangAST import ClassCreatorRest
from JavaLangAST import ClassOrInterfaceType
from JavaLangAST import CompilationUnit
from JavaLangAST import Creator
from JavaLangAST import CreatorArray
from JavaLangAST import CreatorInner
from JavaLangAST import ElementValuePair
from JavaLangAST import Enum
from JavaLangAST import EnumBody
from JavaLangAST import EnumConstant
from JavaLangAST import ExArguments
from JavaLangAST import ExArray
from JavaLangAST import ExArrayIndex
from JavaLangAST import ExCastExpression
from JavaLangAST import ExClass
from JavaLangAST import ExCreator
from JavaLangAST import ExDot
from JavaLangAST import ExIdentifier
from JavaLangAST import ExInnerCreator
from JavaLangAST import ExLiteral
from JavaLangAST import ExOperator
from JavaLangAST import ExParExpression
from JavaLangAST import ExPart
from JavaLangAST import ExPrimary
from JavaLangAST import ExPrimitiveType
from JavaLangAST import ExSuper
from JavaLangAST import ExThis
from JavaLangAST import ExType
from JavaLangAST import ExTypeArguments
from JavaLangAST import ExVoid
from JavaLangAST import Expression
from JavaLangAST import Field
from JavaLangAST import Import
from JavaLangAST import InnerCreator
from JavaLangAST import Interface
from JavaLangAST import InterfaceField
from JavaLangAST import InterfaceMethod
from JavaLangAST import Literal
from JavaLangAST import LocalVariableDeclaration
from JavaLangAST import Method
from JavaLangAST import Modifier
from JavaLangAST import OprAdditive
from JavaLangAST import OprAssign
from JavaLangAST import OprBinary
from JavaLangAST import OprEquality
from JavaLangAST import OprInstanceOf
from JavaLangAST import OprLogical
from JavaLangAST import OprMultiplicative
from JavaLangAST import OprPostfix
from JavaLangAST import OprRelational
from JavaLangAST import OprShift
from JavaLangAST import OprTernary
from JavaLangAST import OprUnary
from JavaLangAST import Parameter
from JavaLangAST import PrimitiveType
from JavaLangAST import QualifiedName
from JavaLangAST import StaticBlock
from JavaLangAST import StmtAssert
from JavaLangAST import StmtBlock
from JavaLangAST import StmtBreak
from JavaLangAST import StmtCatch
from JavaLangAST import StmtContinue
from JavaLangAST import StmtDoWhile
from JavaLangAST import StmtExp
from JavaLangAST import StmtExplicitConstructorInvocation
from JavaLangAST import StmtFor
from JavaLangAST import StmtForEach
from JavaLangAST import StmtIf
from JavaLangAST import StmtLabel
from JavaLangAST import StmtLocalVariableDeclaration
from JavaLangAST import StmtReturn
from JavaLangAST import StmtSemicolon
from JavaLangAST import StmtSwitch
from JavaLangAST import StmtSwitchBlock
from JavaLangAST import StmtSynch
from JavaLangAST import StmtThrow
from JavaLangAST import StmtTry
from JavaLangAST import StmtWhile
from JavaLangAST import Type
from JavaLangAST import TypeArgument
from JavaLangAST import TypeParameter
from JavaLangAST import VariableDeclarator
from JSNI import processNativeCode
import os
from ConfigReader import WAFConfig
#from Compiler import WAFCompileError
import UIControlCompiler


def some_method():
	raise Exception("Critical Error")

class WAFCompileError(StandardError):
	def __init__(self, uid, reftok):
		self.uid = uid
		self.ref = reftok
	def __str__(self):
		if self.ref == None:
			return "UID " + str(self.uid)
		else:
			return "UID " + str(self.uid) + " " + self.ref.data + " Line:" + str(self.ref.lineno) + " Offset:" + str(self.ref.pos)



def check_instance(ob, classes):
	for cls in classes:
		if isinstance(ob, cls):
			return True
	return False


class SA:#Symantec anlysis
	currentClass = None
	currentMethod = None
	currentClasses = []
	calls_model=False
	
	@staticmethod
	def isWrapperClass(t):
		if t.coit==None:return False
		if t.coit.clazz==None:
			raise Exception("UnExpected")
		fname=t.coit.clazz.fullname
		if not fname.startswith("java.lang."):return False
		fname=fname[10:]
		if "." in fname: return False
		return fname in ["Number","Byte","Double","Float","Integer","Long","Short","Boolean","Character"]
	@staticmethod
	def canUnbox(t):
		if t.coit==None:return False
		if t.coit.clazz==None:
			raise Exception("UnExpected")
		fname=t.coit.clazz.fullname
		if not fname.startswith("java.lang."):return False
		fname=fname[10:]
		if "." in fname: return False
		#Only change is 'Number' is excluded since it can not unboxed 
		return fname in ["Byte","Double","Float","Integer","Long","Short","Boolean","Character"]
	
	
	
	@staticmethod
	def fromWrapperClassToBasic(t):
		if t.coit==None:raise "Unexpected"
		if t.coit.clazz==None:raise "UnExpected"
		fname=t.coit.clazz.fullname
		if not fname.startswith("java.lang."):raise "UnExpected"
		fname=fname[10:]
		if "." in fname: raise "UnExpected" 
		if not( fname in ["Number","Byte","Double","Float","Integer","Long","Short","Boolean","Character"]):raise "UnExpected"
		if fname=="Number":
			raise Exception("Can not convert number to basic type")
		if fname=="Byte":return SGlobal.basictypes[PrimitiveType.BYTE]
		if fname=="Double":return SGlobal.basictypes[PrimitiveType.DOUBLE]
		if fname=="Float":return SGlobal.basictypes[PrimitiveType.FLOAT]
		if fname=="Integer":return SGlobal.basictypes[PrimitiveType.INT]
		if fname=="Long":return SGlobal.basictypes[PrimitiveType.LONG]
		if fname=="Short":return SGlobal.basictypes[PrimitiveType.SHORT]
		if fname=="Boolean":return SGlobal.basictypes[PrimitiveType.BOOLEAN]
		if fname=="Character":return SGlobal.basictypes[PrimitiveType.CHAR]
		raise "UnExpected"
	@staticmethod
	def fromBasicToWrapperClass(t):
		if t.pm_type==None: raise "UnExpected"
		v= t.pm_type.value
		SGlobal.initWarraperTypes()#TODO:move this somewhere as need to call only once
		return SGlobal.wrappertypes[v]
	@staticmethod
	def getClassForType(t):
		if t.coit!=None:
			return t.coit.clazz
		if t.pm_type!=None and t.pm_type.value==PrimitiveType.NULL:
			return SGlobal.objclass
		raise "UnExpected"
	@staticmethod
	def isStringType(t):
		if t.coit==None:return False
		if t.coit.clazz==None:raise "UnExpected"
		return t.coit.clazz.fullname=="java.lang.String"			
	@staticmethod
	def hasToString(t):
		raise Exception("not implemented")
	@staticmethod
	def isBasicType(t):
		if t.pm_type == None:
			return False
		if t.pm_type.value== PrimitiveType.NULL:
			return False
		return True
	@staticmethod
	def isBasicNumericType(t):
		if t.pm_type == None: return False
		return t.pm_type.value in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.DOUBLE, PrimitiveType.FLOAT, PrimitiveType.INT, PrimitiveType.LONG, PrimitiveType.SHORT]
	@staticmethod
	def canBeArrayIndex(t):
		if not isinstance(t, Type):return False
		if t.pm_type == None: return False
		return t.pm_type.value in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.SHORT]
	
	@staticmethod
	def checkCompilationUnit(scu):
		sym = []
		sym.append({})
		for d in scu.delcs:
			SA.currentClass=None
			SA.currentMethod=None
			if isinstance(d, SClass):
				SA.checkSClass(d, sym, 0)
			elif isinstance(d, SEnum):
				SA.checkSClass(d, sym, 0)
			elif isinstance(d, SInterface):
				SA.checkSInterface(d, sym, 0)
			elif isinstance(d, SAnnotationType):
				pass
			else:				
				some_method()				
		sym.pop()
	@staticmethod
	def checkSClass(cls, sym, i):
		print "checkSClass ",cls.fullname
		if cls.isAnnotationType(): return
		if cls.fullname.startswith("org.json."):return							
		last_class=SA.currentClass
		last_method=SA.currentMethod		
		SA.currentClass = cls
		sym.append({})
		for im in cls.innerMembers:
			im.setDeclaringClass(cls)
			if isinstance(im, SClass):
				SA.checkSClass(im, sym, i + 1)
			elif isinstance(im, SInterface):
				SA.checkSInterface(im, sym, i + 1)
			elif isinstance(im, SEnum):
				SA.checkSClass(im, sym, i + 1)
			else:
				some_method()
			SA.currentClass = cls
		for f in cls.fields:
			f = cls.fields[f]
			if f.isStatic():
				if f.init != None:
					if isinstance(f.init, Expression):
						SA.checkExpression(f.init, sym, i +1)
					elif isinstance(f.init, ArrayInitializer):
						SA.checkArrayInitializer(f.init, sym, i +1)
					else:						
						raise WAFCompileError("");		
		SA.checkMethods(cls, sym, i + 1)
		SA.checkConstructors(cls, sym, i + 1)
		vfname=cls.getCompilationUnit().filepath
		vfname=vfname[:-5]+".view.html"
		if (not cls.isInner()) and os.path.exists(vfname):
			try:
				UIControlCompiler.markRefsForControl(vfname, cls)
			except Exception as ex:
				print "Exception while processing "+vfname
				print ex
				sys.exit(0)
		SA.currentMethod=last_method
		if cls.hasStaticBlocks():
			for b in cls.static_blocks:
				SA.checkBlock(b, sym, i +1)
			if cls.hasInstanceStaticBlocks():
				for b in cls.instance_static_blocks:
					SA.checkBlock(b, sym, i +1)					
		SA.currentClass=last_class				
		sym.pop()

	@staticmethod
	def checkSInterface(ifc, sym, i):
		#if ifc.fullname.startswith("waf.common.annotation.") or ifc.fullname.startswith("java.lang.annotation"):
		#	return
		if ifc.isAnnotationType(): return
		last_class=SA.currentClass
		last_method=SA.currentMethod	
		SA.currentClass = ifc
		sym.append({})
		for im in ifc.innerMembers:
			im.setDeclaringClass(ifc)
			if isinstance(im, SClass):
				SA.checkSClass(im, sym, i + 1)
			elif isinstance(im, SInterface):
				SA.checkSInterface(im, sym, i +1)
			elif isinstance(im, SEnum):
				SA.checkSClass(im, sym, i +1 )
			else:				
				some_method()
			SA.currentClass = ifc
		SA.checkMethods(ifc, sym, i + 1)
		for f in ifc.fields:
			f = ifc.fields[f]
			if f.isStatic():
				if f.init != None:
					if isinstance(f.init, Expression):
						SA.checkExpression(f.init, sym, i +1)
					elif isinstance(f.init, ArrayInitializer):
						SA.checkArrayInitializer(f.init, sym, i +1)
					else:				
						raise WAFCompileError("");
			else:				
				some_method()
		SA.currentMethod=last_method
		if ifc.hasStaticBlocks():
			for b in ifc.static_blocks:
				SA.checkBlock(b, sym, i +1 )
		sym.pop()
		SA.currentClass=last_class
		
	@staticmethod
	def checkConstructors(cls, sym, i):		
		for c in cls.constructors:
			if c.rettype != None:
				raise WAFCompileError(1003, c.name)
			SA.checkConstructorDuplication(c, cls)
			SA.checkConstructor(c, cls, sym, i)
	@staticmethod
	def checkMethods(cls, sym, i):
		m=False
		for c in cls.methods:
			if SA.checkMethod(c, cls, sym, i):
				m=True
		if m==True:			
			SA.checkMethods(cls,sym, i)
	@staticmethod
	def checkMethod(c, cls, sym, i):
		old_value=c.calls_model
		SA.calls_model=False
		outer_method=SA.currentMethod
		SA.currentMethod = c
		m = c.method
		sym.append({})
		i = i + 1
		if c.is_void == False:
			SHelper.processType(c.rettype, SA.currentClass, SA.currentMethod)
		for p in c.pars:
			SHelper.processType(p.typ, SA.currentClass, SA.currentMethod)
			sym[i][p.name.data] = p
		if m.block != None:
			if	cls.isModelClass()==False:
				SA.checkBlockStatements(m.block, sym, i)
		else:
			if c.native_code != None:				
				toks = processNativeCode(c.native_code)
				SA.checkNativeCode(toks,c)
		sym.pop()
		SA.currentMethod=outer_method
		if outer_method!=None:
			for i in c.refs:
				if i not in outer_method.refs:
					outer_method.refs.append(i)
		if SA.calls_model==True:
			c.calls_model=True
		SA.calls_model=False
		if old_value==False and c.calls_model==True:
			return True
		return False
		
	@staticmethod
	def checkNativeCode(toks,method):
		from JSNI import NTypeField, NTypeName, NDot
		from Tokenizer import Token
		skip_next_token = False
		for ct in toks:
			if isinstance(ct, Token):
				if WAFConfig.isMinify()and(ct.data.startswith("//") or ct.data.startswith("/*")):
					continue
				if skip_next_token == True:
					skip_next_token = False
					continue				
			elif isinstance(ct, list):
				nei = 0
				t_nei = len(ct)
				accessing_static = True
				if isinstance(ct[0], NDot):
					nei = 1
					accessing_static = False
				if not isinstance(ct[nei], NTypeName):some_method()
				s = []
				for n in ct[nei].names:
					s.append(n.data)
				name = ".".join(s)
				inner_class_name = None
				accessing_inner_class = False
				outer_class = None
				base_class = None
				if "$" in name:
					[name, sep, inner_class_name] = name.rpartition("$")
					outer_class = SHelper.getClassOnFullName(name)
					if outer_class == None:
						print "Class not found in native code name ", name
						some_method()
					accessing_inner_class = True						
					base_class = outer_class.getInnerMember(inner_class_name)
					if base_class == None:
						print "Inner class not found to " + name + " with name " + inner_class_name + " in native code "
						some_method()
				else:
					base_class = SHelper.getClassOnFullName(name)
					if base_class == None:
						print "Class not found in native code", name
						some_method()

				nei += 1
				f = ct[nei]
				if not isinstance(f, NTypeField):some_method()
				nei += 1
				fname = f.name.data
				if t_nei == nei:
					f = base_class.getFieldWithThisAccess(fname, accessing_static, SA.currentClass)
					if f != None:
						if f.field.isStatic() == True and accessing_static == False:
							print "Can not access static member " + fname + " " + base_class.getFullname()
							some_method()
						SA.addMethodRef(f.field.mid)
					else:
						if accessing_static == False:
							f = base_class.getFieldFromContainerClass(fname, accessing_static, SA.currentClass)
							if f == None:
								print "Data member not found in native code " + fname + " " + base_class.getFullname()
								some_method()
							SA.addMethodRef(f.field.mid)
						else:
							print "Field not found in native code for static access " + fname + " for class " + base_class.getFullname()
							some_method()
				else:
					nt = ct[nei]
					if not isinstance(nt, list):
						print "non list", some_method()
					types = []
					for ta in nt:
						s = []
						for n in ta.names:
							s.append(n.data)
						name = ".".join(s)
						if len(name) > 1:	
							name = name[1:]#remove L
							arg_class = SHelper.getClassOnFullName(name)
							if arg_class == None:
								print "arg type not found", name
								some_method()
							#print name
							types.append(arg_class.mytype)
						else:
							if name == "I":
								types.append(SGlobal.basictypes[PrimitiveType.INT])
							else:
								print "not handled ", name
								some_method()
					if fname == "new":
						if accessing_inner_class == True:
							cons = base_class.getConstructor(types, SA.currentClass)
							if cons == None:
								print "matcing constructor not found in native code for " + base_class.getFullname()
								some_method()
							SA.addMethodRef(cons.mid)
						else:
							cons = base_class.getConstructor(types, SA.currentClass)
							if cons == None:
								print "matcing constructor not found in native code for " + base_class.getFullname()
								cons = base_class.getConstructor(types, SA.currentClass)
								some_method()
							SA.addMethodRef(cons.mid)
					else:
						###### FOR IE 6 native
						if base_class.package=="com.openwaf.client.dom" and WAFConfig.isCompatibleWithIE67():
							if base_class!=SA.currentClass:
								print "Problem",some_method()														
							m = base_class.getMethodWithThisAccess(fname, types, accessing_static, None,SA.currentClass)
							if m==None:
								raise Exception("Method not found "+fname)
							SA.addMethodRef(m.method.mid)
						###### FOR IE 6 native						
						else:
							m = base_class.getMethodWithThisAccess(fname, types, accessing_static, None,SA.currentClass)
							if m != None:
								SA.addMethodRef(m.method.mid)
							else:
								if accessing_static == False:
									m = base_class.getMethodFromContainerClass(fname, types, accessing_static, SA.currentClass)
									if m == None:
										print "Method not found in native code " + fname + " " + base_class.getFullname()
										some_method()
									SA.addMethodRef(m.method.mid)
								else:
									print "Method not found in native code " + fname + " " + base_class.getFullname()
									some_method()
			else:
				print "What is this"
				print ct
				some_method()

	@staticmethod
	def checkConstructor(c, cls, sym, i):
		SA.calls_model=False
		outer_method=SA.currentMethod
		SA.currentMethod = c
		if c.isDefaultConstructor():
			if WAFConfig.isRemoveUnusedCode():
				if cls.exclass != None and len(cls.exclass) == 1:#calling default constructor automatically
					ex = cls.exclass[0]
					mc=ex.getConstructor([], SA.currentClass)
					if mc==None:
						if ex.fullname == "java.lang.Enum":
							pass
						elif len(ex.constructors) > 0:
							raise WAFCompileError(1005, ex.fullname)
					SA.addMethodRef(mc.mid)
			return
		m = c.method
		eci = None
		if m != None:
			eci = m.explconinv
		sym.append({})
		i = i + 1
		for p in c.pars:
			SHelper.processType(p.typ, SA.currentClass, SA.currentMethod)
			sym[i][p.name.data] = p
		if eci != None:
			if eci.is_super:
				if (cls.exclass == None or len(cls.exclass) == 0) and eci != None:
					raise WAFCompileError(1006, cls.name)
				ex = cls.exclass[0]
				mc=ex.getConstructor(SA.getExpressionListToTypeList(eci.arguments, sym, i), SA.currentClass)
				if mc==None:
					raise WAFCompileError("Super Constructor not found", None)
				if WAFConfig.isRemoveUnusedCode():
					SA.addMethodRef(mc.mid)
			elif eci.is_this:
				mc=cls.getConstructor(SA.getExpressionListToTypeList(eci.arguments, sym, i), SA.currentClass)
				if m==None:
					raise WAFCompileError("Super Constructor not found", None)
				if WAFConfig.isRemoveUnusedCode():
					SA.addMethodRef(mc.mid)
				
		if cls.exclass != None and len(cls.exclass) == 1 and eci == None:#calling default constructor automatically
			ex = cls.exclass[0]
			mc=ex.getConstructor([], SA.currentClass)
			if mc==None:
				if ex.fullname == "java.lang.Enum":
					pass
				elif len(ex.constructors) > 0:
					raise WAFCompileError(1005, ex.fullname)
			if mc!=None and WAFConfig.isRemoveUnusedCode():
				SA.addMethodRef(mc.mid)
		if m != None:
			for s in m.stmts:
				SA.checkStmt(s, sym, i)
		sym.pop()
		SA.currentMethod=outer_method
		if outer_method!=None:
			for i in c.refs:
				if i not in outer_method.refs:
					outer_method.refs.append(i)
		if SA.calls_model==True:
			c.calls_model=True
		SA.calls_model=False
	
	@staticmethod
	def checkConstructorDuplication(c, cls):
		for m in cls.constructors:
			if c == m:continue
			if c.matchPars(m.pars):
				raise WAFCompileError(1004, c.name)

	
	@staticmethod
	def checkClassMethod(m, sym, i):
		pass

	@staticmethod
	def checkFormalParameters(pars, sym, i):
		pass



	@staticmethod
	def checkStmt(st, sym, i):
		if check_instance(st, [StmtForEach, StmtLocalVariableDeclaration, StmtAssert, StmtBlock, StmtBreak, StmtIf, StmtFor, StmtWhile, StmtDoWhile, StmtSwitch, StmtReturn, StmtThrow, StmtContinue, StmtTry, StmtExp]):
			r=None
			calls_model=SA.calls_model
			SA.calls_model=False
			if isinstance(st, StmtAssert):	r=SA.checkStmtAssert(st, sym, i)
			elif isinstance(st, StmtBlock):	r=SA.checkBlock(st, sym, i)
			elif isinstance(st, StmtBreak):	r=SA.checkStmtBreak(st, sym, i)
			elif isinstance(st, StmtContinue):  r=SA.checkStmtContinue(st, sym, i)
			elif isinstance(st, StmtFor):		r=SA.checkStmtFor(st, sym, i)
			elif isinstance(st, StmtIf):	 	r=SA.checkStmtIf(st, sym, i)
			elif isinstance(st, StmtLocalVariableDeclaration):	   r=SA.checkStmtLocalVariableDeclaration(st, sym, i)
			elif isinstance(st, StmtReturn): 	r=SA.checkStmtReturn(st, sym, i)
			elif isinstance(st, StmtSwitch): 	r=SA.checkStmtSwitch(st, sym, i)
			elif isinstance(st, StmtThrow):  	r=SA.checkStmtThrow(st, sym, i)
			elif isinstance(st, StmtTry):		r=SA.checkStmtTry(st, sym, i)
			elif isinstance(st, StmtWhile):	r=SA.checkStmtWhile(st, sym, i)
			elif isinstance(st, StmtDoWhile):	r=SA.checkStmtDoWhile(st, sym, i)
			elif isinstance(st, StmtExp):	r=SA.checkStmtExp(st, sym, i)
			elif isinstance(st, StmtForEach):r=SA.checkStmtForEach(st, sym, i)
			else:
				print "Unexpected ", SA.ttos(st)
				some_method()
			if SA.calls_model==True or (isinstance(st,StmtIf) and st.par_ex_calls_model==True):
				st.calls_model=True
				SA.calls_model=True
			else:
				SA.calls_model=calls_model
			
			return r
		else:
			print "KKK", SA.ttos(st)
			some_method()
	@staticmethod
	def checkStmtAssert(st, sym, i):
		SA.checkExpression(st.exp1, sym, i)
		if st.exp2 != None:
			SA.checkExpression(st.exp2, sym, i)
		#TODO:
		return None

	@staticmethod
	def checkStmtBlock(st, sym, i):#complete
		#TODO:to update index
		return SA.checkBlock(st.block, sym, i)

	@staticmethod
	def checkStmtBreak(st, sym, i):#complete
		return

	@staticmethod
	def checkStmtContinue(st, sym, i):#complete
		return

	@staticmethod
	def checkStmtIf(st, sym, i):#complete
		SA.checkParExpression(st.par, sym, i)
		if SA.calls_model==True:
			st.par_ex_calls_model=True
			SA.calls_model=False			
		SA.checkStmt(st.stmt_if, sym, i)
		if st.stmt_else != None:
			SA.checkStmt(st.stmt_else, sym, i)

	@staticmethod
	def checkStmtFor(st, sym, i):#complete
		sym.append({})
		if st.init != None:
			SA.checkForInit(st.init, sym, i + 1)
		if st.cond != None:
			SA.checkExpression(st.cond, sym, i + 1)

		SA.checkExpressionList(st.exps, sym, i + 1)
		SA.checkStmt(st.stmt, sym, i + 1)
		sym.pop()

	@staticmethod
	def checkStmtForEach(st, sym, i):
		#TODO:check this type is not processed
		sym.append({})
		SA.checkLocalVariableDeclaration(st.vd, sym, i + 1)
		SA.checkExpression(st.exps, sym, i + 1)
		SA.checkStmt(st.stmt, sym, i + 1)
		sym.pop()

	@staticmethod
	def checkForInit(st, sym, i):#complete
		if isinstance(st, LocalVariableDeclaration):
			return SA.checkLocalVariableDeclaration(st, sym, i)
		return SA.checkExpressionList(st, sym, i)

	@staticmethod
	def checkExpressionList(el, sym, i):#complete
		if el == None:return
		if not isinstance(el, list):
			print "Expecting list in CheckExpressionList"
			raise WAFCompileError(None, None)
		for e in el:
			SA.checkExpression(e, sym, i)

	@staticmethod
	def checkStmtLocalVariableDeclaration(st, sym, i):
		return SA.checkLocalVariableDeclaration(st.lvd, sym, i)
	@staticmethod
	def checkStmtWhile(st, sym, i):#complete
		SA.checkParExpression(st.par, sym, i)
		SA.checkStmt(st.stmt, sym, i)

	@staticmethod
	def checkStmtDoWhile(st, sym, i):#complete
		SA.checkStmt(st.stmt, sym, i)
		SA.checkParExpression(st.par, sym, i)

	@staticmethod
	def checkStmtSwitch(st, sym, i):#complete
		t = SA.checkParExpression(st.par, sym, i)
		sym.append({})
		cls = None
		if t.coit != None and t.coit.clazz != None:
			if isinstance(t.coit.clazz, SEnum):
				cls = t.coit.clazz;				
				for name in cls.constants_hash:
					sym[i + 1][name] = cls.mytype
		for b in st.cases:
			if b.default == False:
				SA.checkExpression(b.exp, sym, i + 1)
		sym.pop()
		for b in st.cases:
			SA.checkSwitchBlock(b, sym, i)
	@staticmethod
	def checkSwitchBlock(sb, sym, i):#complete
		for st in sb.stmts:
			SA.checkBlockStatement(st, sym, i)

	@staticmethod
	def checkStmtReturn(st, sym, i):#complete
		if st.exp != None:
			SA.checkExpression(st.exp, sym, i)

	@staticmethod
	def checkStmtThrow(st, sym, i):#complete
		SA.checkExpression(st.exp, sym, i)


	@staticmethod
	def checkBlock(b, sym, i):#complete
		sym.append({})
		SA.checkBlockStatements(b.block, sym, i + 1)
		sym.pop()

	@staticmethod
	def checkBlockStatements(sts, sym, i):#complete
		for st in sts:
			SA.checkBlockStatement(st, sym, i)

	@staticmethod
	def checkBlockStatement(st, sym, i):#complete
		#TODO:check this
		if isinstance(st, LocalVariableDeclaration):
			return SA.checkLocalVariableDeclaration(st, sym, i)
		if check_instance(st, [Class, Enum]):
			some_method()
			return ""
		SA.checkStmt(st, sym, i)


	@staticmethod
	def checkStmtTry(st, sym, i):#inomplete
		SA.checkBlock(st.tryblock, sym, i)
		for ct in st.catches:
			sym.append({})
			SHelper.processType(ct.param.typ, SA.currentClass, None)
			sym[i + 1][ct.param.name.data] = ct.param
			SA.checkBlock(ct.block, sym, i + 1)
			sym.pop()
		if st.finallyblock != None:
			SA.checkBlock(st.finallyblock, sym, i)
		
			
		
		#TODO:check exception
	@staticmethod
	def checkParameter(p, sym, i):#complete
		SA.checkIdentifier(p.name)
	@staticmethod
	def checkStmtExp(st, sym, i):#complete
		return SA.checkExpression(st.exp, sym, i)

	@staticmethod
	def checkParExpression(e, sym, i):#complete
		return SA.checkExpression(e.exp, sym, i)


	@staticmethod
	def checkIdentifier(idf):#complete
		#TODO:we might need do something here
		#return idf.data
		pass


	@staticmethod
	def checkLocalVariableDeclaration(lvd, sym, i):#complete
		for vd  in lvd.vds:
			SA.checkVariableDeclarator(vd, lvd.modifiers, sym, i)
		#TODO:add symbols here

	@staticmethod
	def checkVariableDeclarator(vd, modifiers, sym, i):#complete
		t = vd.typ
		SHelper.processType(t, SA.currentClass, SA.currentMethod)
		line = vd.name.data
		if line == None:raise WAFCompileError(-1, "Critical Error")
		if sym[i].has_key(line):
			print "Duplicate variable in same block ", line
			print line
			print vd.name.lineno, vd.name.pos
			raise WAFCompileError(1001, vd.name)
		sym[i][line] = t#Var(line,vd.typ,vd.arraydim,modifiers)#TODO;what the hell is this
		if vd.init != None:
			SA.checkVariableInitializer(vd.init, sym, i)


	@staticmethod
	def checkVariableInitializer(vi, sym, i):#complete
		if isinstance(vi, ArrayInitializer):
			return SA.checkArrayInitializer(vi, sym, i)
		else:#expression
			return SA.checkExpression(vi, sym, i)


	@staticmethod
	def checkArrayInitializer(ai, sym, i):#complete #not_tested
		for vi in ai.part:
			SA.checkVariableInitializer(vi, sym, i)
	@staticmethod
	def isDeclaration(t):
		return isinstance(t, STypeDeclaration)
	@staticmethod
	def mapTypeArgument(curType, tp):
		if curType.coit.typeargs != None and len(curType.coit.typeargs) > tp.index:
			ta = curType.coit.typeargs[tp.index]
			if ta.isany == True:
				if ta.extends == None:
					return SGlobal.objclass.mytype
				else:
					return ta.extends
			else:
				if ta.typ != None:
					return ta.typ
				print some_method()#TODO:debug
		else:
			return SGlobal.objclass.mytype

	@staticmethod
	def getTypeDeclaration(t):
		if t == None:
			print "not expected"
			some_method()
		if isinstance(t, Type) and t.coit != None:
			cls = t.coit.clazz
			if isinstance(cls, STypeDeclaration):
				return cls
			if isinstance(cls, TypeParameter):
				if cls.bound != None:
					if len(cls.bound) == 1:
						return cls.bound[0].coit.clazz
					else:
						print "Multiple bounds"
						some_method()
						sys.exit()
				return SGlobal.objclass
			print SA.ttos(cls)
			some_method()
		elif isinstance(t, STypeDeclaration):
			return t
		else:
			print SA.ttos(t)
			some_method()
	@staticmethod
	def mapTypeToTypeArgument(_typeargs, type):
		if _typeargs == None: return type
		if isinstance(type, Type) and type.coit != None and isinstance(type.coit.clazz, TypeParameter):
			for t in _typeargs:
				if t.ref == type.coit.clazz:
					if t.isany == False:
						return t.typ
					if t.extends != None:
						return t.extends
					if t.superclass != None:
						return t.superclass
					if t.isany == True:
						return SGlobal.objclass.mytype
					print "UnExpected"
					sys.exit()
						
		return type
	"""		
	@staticmethod
	def collectTypeArgs(type,_typeargs):
		if isinstance(type,Type) and type.coit!=None and type.coit.typeargs!=None:
			if _typeargs==None:_typeargs=[]
			i=0
			for _t in type.coit.typeargs:
				_typeargs.append(_t)
				_t.ref=type.coit.clazz.typepars[i]
				if _t.typ!=None:SA.collectTypeArgs(_t.typ,_typeargs)
				if _t.extends!=None:SA.collectTypeArgs(_t.extends,_typeargs)
				if _t.superclass!=None:SA.collectTypeArgs(_t.superclass,_typeargs)				
				i+=1
			
		return _typeargs
	"""
	@staticmethod
	def addMethodRef(mid):
		if SA.currentMethod!=None:
			if id not in SA.currentMethod.refs:
				SA.currentMethod.refs.append(mid)
			if not SGlobal.method_refs.has_key(SA.currentMethod.mid):
				SGlobal.method_refs[SA.currentMethod.mid]=SA.currentMethod
		else:
			SGlobal.static_refs.append(mid)
		if id not in SA.currentClass.refs:
			SA.currentClass.refs.append(mid)
		if not SGlobal.class_refs.has_key(SA.currentClass.clsid):
			SGlobal.class_refs[SA.currentClass.clsid]=SA.currentClass
	@staticmethod
	def checkDotDotExpression(curType, parts, pi, pcount, sym, i):
		#TODO:temp solution
		if SA.isDeclaration(curType):#for static
			if SGlobal.wafmodel==None:
				SGlobal.initWarraperTypes()
			
			method_type_args=None
			if isinstance(parts[pi], ExTypeArguments):
				method_type_args=[]				
				for arg in parts[pi].typeargs:
					SHelper.processType(arg, SA.currentClass, SA.currentMethod)
					ta = TypeArgument()
					ta.isany = False              		
					ta.typ = curType.mytype.mapAndConvertType(arg,None,SA.currentMethod)
					method_type_args.append(ta)
				pi+=1
			if isinstance(parts[pi], ExIdentifier):
				name = parts[pi].name.data
				if (pi + 1) < pcount and isinstance(parts[pi + 1], ExArguments):
					args = parts[pi + 1].arguments
					argstl = SA.getExpressionListToTypeList(args, sym, i)
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curType.mytype.mapAndConvertType(_arg,None,SA.currentMethod))
					argstl = _argstl
					m = None
					
					m = curType.getMethodWithThisAccess(name, argstl, True,method_type_args, SA.currentClass)
					
					if m == None:
						m=curType.getMethodWithThisAccess(name, argstl, True,method_type_args, SA.currentClass)
						cc = SA.getTypeDeclaration(curType)
						print name
						print cc.fullname
						print parts[pi].name.lineno
						raise WAFCompileError(1008, parts[pi].name)
					if curType.getDegreeWithThis(SGlobal.wafmodel)>=0:
						import Java2js_SCS
						if Java2js_SCS.SCS.checkAsyncModelCall(m.method, curType)==None:
							SA.calls_model=True
					if WAFConfig.isRemoveUnusedCode():
						SA.addMethodRef(m.method.mid)
					if not m.method.isStatic():
						raise WAFCompileError(1014, parts[pi].name)
					if m.method.is_void == True:return None
					r = curType.mytype.mapAndConvertType(m.rtype,method_type_args,m.method)
					if pi + 2 == pcount:return r
					np=parts[pi + 2]
					if isinstance(np, ExDot):					
						return SA.checkDotDotExpression(r, parts, pi + 3, pcount, None, sym, i)
					if isinstance(np,ExArrayIndex):
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, None, sym, i)
					raise WAFCompileError(0, "what is this in method")
				else:
					f = None
					f = curType.getFieldWithThisAccess(name, True, SA.currentClass)
					if f == None:
						f = curType.getFieldWithThisAccess(name, True, SA.currentClass)
						print name, SA.currentClass.fullname, SA.currentMethod.name, curType.fullname
						raise WAFCompileError(1008, parts[pi].name)
					if SA.isDeclaration(f):
						if pi + 1 == pcount:return f
						if isinstance(parts[pi + 1], ExDot):
							return SA.checkDotDotExpression(f, parts, pi + 2, pcount, sym, i)
						some_method() 
					r = f.type
					if pi + 1 == pcount:return r
					if isinstance(parts[pi + 1], ExDot):
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
					if isinstance(parts[pi + 1], ExArrayIndex):
						return SA.checkDotDotExpression(r, parts, pi + 1, pcount, sym, i)

					raise WAFCompileError(0, "what is this")
			elif  isinstance(parts[pi], ExClass):
				if pi + 1 == pcount:
					return SHelper.getClassOnFullName("java.lang.Class").mytype
				if isinstance(parts[pi + 1], ExDot):
					#TODO:need to correct this class type
					return SA.checkDotDotExpression(curType, parts, pi + 2, pcount, None, sym, i)
				#TODO:Process
			elif isinstance(parts[pi], ExThis):
				if pi + 1 == pcount:return curType.mytype
				if isinstance(parts[pi + 1], ExDot):
					return SA.checkDotDotExpression(curType.mytype, parts, pi + 2, pcount, None, sym, i)
			print curType.fullname
			print SA.toSParts(parts)
			some_method()

		SHelper.processType(curType, SA.currentClass, SA.currentMethod)
		method_type_args=None
		if isinstance(parts[pi], ExTypeArguments):
			method_type_args=[]				
			for arg in parts[pi].typeargs:
				SHelper.processType(arg, SA.currentClass, SA.currentMethod)
				ta = TypeArgument()
				ta.isany = False              		
				ta.typ =curType.mapAndConvertType(arg,None,SA.currentMethod)
				method_type_args.append(ta)
			pi+=1
		if curType.coit != None:
			if isinstance(parts[pi], ExIdentifier):
				name = parts[pi].name.data
				if (pi + 1) < pcount and isinstance(parts[pi + 1], ExArguments):
					args = parts[pi + 1].arguments
					argstl = SA.getExpressionListToTypeList(args, sym, i)
					#_argstl = []
					#for _arg in argstl: 
					#	_argstl.append(SA.currentClass.mapAndConvertType(_arg,None,SA.currentClass))
					#argstl=_argstl
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curType.mapAndConvertType(_arg,None,SA.currentMethod))
					argstl = _argstl

					m = curType.getMethodWithThisAccess(name, argstl, False,method_type_args, SA.currentClass)
					if m == None:
						m = curType.getMethodWithThisAccess(name, argstl, False,method_type_args, SA.currentClass)
						argstl = SA.getExpressionListToTypeList(args, sym, i)
						print SA.ttos(curType)
						print SA.currentClass.fullname
						cc = SA.getTypeDeclaration(curType)
						print cc.fullname	
						print parts[pi].name.lineno
						print name
						print method_type_args
						raise WAFCompileError(1008, parts[pi].name)
					if WAFConfig.isRemoveUnusedCode():
						SA.addMethodRef(m.method.mid)
					if m.method.is_void == True:return None
					r = curType.mapAndConvertType(m.rtype,method_type_args,m)	
					if pi + 2 == pcount:return r
					if isinstance(parts[pi + 2], ExDot):
						return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i)
					if isinstance(parts[pi + 2], ExArrayIndex):
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
					raise WAFCompileError(0)
				else:
					f = curType.getFieldWithThisAccess(name, False, SA.currentClass)
					if f == None:raise WAFCompileError(1009, parts[pi].name)
					r = curType.mapAndConvertType(f.type,None,SA.currentMethod)					
					#TODO:Map type args here
					if pi + 1 == pcount:return r
					if isinstance(parts[pi + 1], ExDot):
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
					elif isinstance(parts[pi + 1], ExArrayIndex):
						return SA.checkDotDotExpression(r, parts, pi + 1, pcount, sym, i)
					raise WAFCompileError(0)
			elif isinstance(parts[pi], ExArrayIndex):
				if  curType.coit == None or curType.coit.clazz != SGlobal.arrayclass:
					raise WAFCompileError(-1, "Not an array exception")
				p = parts[pi]
				t = SA.checkExpression(p.exp, sym, i)
				if isinstance(t, Type):
					if not SA.canBeArrayIndex(t):
						raise WAFCompileError("Can not evaluate to positive integer")
				else:
					raise WAFCompileError("Can not evaluate to positive integer")
				r=SA.getTypeWithReducedArray(curType)
				if pi + 1 == pcount:return r
				if isinstance(parts[pi+1],ExDot):
					return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
				if isinstance(parts[pi+1],ExArrayIndex):
					return SA.checkDotDotExpression(r, parts, pi + 1, pcount, sym, i)
				raise Exception("Syntax Error")
			else:
				print pi
				print SA.toSParts(parts)
				print SA.toSParts(parts[pi])
				raise WAFCompileError("What is this")
		else:
			if isinstance(parts[pi], ExArrayIndex):
				if curType.coit == None or curType.coit.clazz != SGlobal.arrayclass:
					raise WAFCompileError(-1, "Not an array exception")
				p = parts[pi]
				t = SA.checkExpression(p.exp, sym, i)
				if isinstance(t, Type):
					if not SA.canBeArrayIndex(t):
						raise WAFCompileError("Can not evaluate to positive integer")
				else:
					raise WAFCompileError("Can not evaluate to positive integer")
				r=SA.getTypeWithReducedArray(curType)
				if pi + 1 == pcount:r
				if isinstance(parts[pi+1],ExDot):
					return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
				if isinstance(parts[pi+1],ExArrayIndex):
					return SA.checkDotDotExpression(r, parts, pi + 1, pcount, sym, i)
			raise WAFCompileError(-1)


	@staticmethod
	def getExpressionListToTypeList(el, sym, i):#incomplete tested
		ts = []
		for e in el:
			r = SA.checkExpression(e, sym, i)
			if r == None:
				raise WAFCompileError(0, "Invalid argument")#TODO:change this
			ts.append(r)
		return ts
	@staticmethod
	def checkExpression(e, sym, i):#incomplete
		return SA.checkExpressionArray(e.parts, sym, i)
		#this shoudl return Type or none
	@staticmethod
	def isExpressionTuple(p):#incomplete
		if not isinstance(p, list):return False
		l = len(p)
		if l > 3 or l < 1:return False
		if l == 2 and isinstance(p[0], ExOperator):
			return True
		elif (l == 2 or l == 3) and isinstance(p[1], ExOperator):
			return True
		return False
	@staticmethod
	def checkTuplePart(part, sym, i):
		if SA.isExpressionTuple(part):
			return SA.checkExpressionTuple(part, sym, i)
		elif isinstance(part, ExPrimary):
			return SA.checkExpressionArray(part.parts, sym, i)
		else:
			return SA.checkExpressionArray(part, sym, i)
			
	@staticmethod
	def checkExpressionTuple(p, sym, i):
		l = len(p)
		if l == 2 and isinstance(p[0], ExOperator):
			o = p[0]
			if not o.value >= OprUnary.INC and o.value <= OprUnary.TILDE:
				raise WAFCompileError(-1, "Wrong operator prefix")#TODO
			t = SA.checkTuplePart(p[1], sym, i)
			if o.value == OprUnary.TILDE:
				if not (SA.isBasicNumericType(t) and t.pm_type.value in [ PrimitiveType.INT,PrimitiveType.LONG,PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]):
					raise WAFCompileError(1011, None)
				if t.pm_type.value in [PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]:
					return SGlobal.basictypes[PrimitiveType.INT]
				return t#int or long
			elif o.value == OprUnary.NOT:
				if not ( SA.isBasicType(t)  and t.pm_type.value == PrimitiveType.BOOLEAN):
					raise WAFCompileError(1012, None)
				return t
			elif o.value in [OprUnary.DEC, OprUnary.INC]:
				if not SA.isBasicNumericType(t):
					raise WAFCompileError(1013, None)
				return t
			elif o.value in [OprUnary.NEGATIVE, OprUnary.POSITIVE]:
				if not SA.isBasicNumericType(t):
					raise WAFCompileError(1013, None)
				if t.pm_type.value in [PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]:
					return SGlobal.basictypes[PrimitiveType.INT]
				return t
			raise WAFCompileError(-1)
		elif l == 2 and isinstance(p[1], ExOperator):
			o = p[1].value
			t = SA.checkTuplePart(p[0], sym, i)

			if not o in [OprPostfix.DEC, OprPostfix.INC]:
				raise WAFCompileError(-1, "Wrong Operator postfix")#TODO
			if not SA.isBasicNumericType(t):
				raise WAFCompileError(1013, None)
			return t
		elif l == 3 and isinstance(p[1], ExOperator):
			o = p[1].value
			t1 = SA.checkTuplePart(p[0], sym, i)
			t2 = SA.checkTuplePart(p[2], sym, i)
			if t1==None or t2==None:
				t1 = SA.checkTuplePart(p[0], sym, i)
				t2 = SA.checkTuplePart(p[2], sym, i)
				print SA.currentMethod.name
				print t1,t2
				print o
				print p[0]
				print p[2]
				some_method()
			if o in [OprMultiplicative.DIVIDE,OprMultiplicative.MULTIPY,OprMultiplicative.MOD,OprAdditive.MINUS,OprAdditive.PLUS,OprBinary.AND,OprBinary.OR,OprBinary.XOR]:
				if o==OprAdditive.PLUS:
					if SA.isStringType(t1) or SA.isStringType(t2):
						return SGlobal.stringclass.mytype
				if SA.isBasicNumericType(t1) and SA.isBasicNumericType(t2):
					dt1=t1.pm_type.value
					dt2=t2.pm_type.value
					if o in [OprBinary.AND,OprBinary.OR,OprBinary.XOR]:
						if dt1 in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
							raise Exception("Shift can not be applied on float or double")
						if dt2 in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
							raise Exception("Shift can not be applied on float or double")
					dt=max(dt1,dt2)
					if dt in [PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]:
						return SGlobal.basictypes[PrimitiveType.INT]
					return SGlobal.basictypes[dt]
				elif (SA.isBasicNumericType(t1) and SA.isWrapperClass(t2)) or (SA.isBasicNumericType(t2) and SA.isWrapperClass(t1)):
					if SA.isBasicNumericType(t1):
						if not SA.canUnbox(t2):raise Exception("Can not unbox ")
						ub_dt2=SA.fromWrapperClassToBasic(t2)
						dt1=t1
						if o in [OprBinary.AND,OprBinary.OR,OprBinary.XOR]:
							if dt1.pm_type.value in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
								raise Exception("Shift can not be applied on float or double")
							if ub_dt2.pm_type.value in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
								raise Exception("Shift can not be applied on float or double")
						dt=max(dt1.pm_type.value,ub_dt2.pm_type.value)
						if dt in [PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]:
							return SGlobal.basictypes[PrimitiveType.INT]
						return SGlobal.basictypes[dt]
					else:
						if not SA.canUnbox(t1):raise Exception("Can not unbox ")
						ub_dt1=SA.fromWrapperClassToBasic(t1)
						dt2=t2
						if o in [OprBinary.AND,OprBinary.OR,OprBinary.XOR]:
							if dt2.pm_type.value in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
								raise Exception("Shift can not be applied on float or double")
							if ub_dt1.pm_type.value in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
								raise Exception("Shift can not be applied on float or double")
						dt=max(dt2.pm_type.value,ub_dt1.pm_type.value)
						if dt in [PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]:
							return SGlobal.basictypes[PrimitiveType.INT]
						return SGlobal.basictypes[dt] 					
				elif SA.isWrapperClass(t1) or SA.isWrapperClass(t2):
					if not SA.canUnbox(t1):raise Exception("Can not unbox")
					if not SA.canUnbox(t2):raise Exception("Can not unbox")
					ub_dt1=SA.fromWrapperClassToBasic(t1)
					ub_dt2=SA.fromWrapperClassToBasic(t2)
					if o in [OprBinary.AND,OprBinary.OR,OprBinary.XOR]:
						if ub_dt1.pm_type.value in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
							raise Exception("Shift can not be applied on float or double")
						if ub_dt2.pm_type.value in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
							raise Exception("Shift can not be applied on float or double")
					dt=max(ub_dt1.pm_type.value,ub_dt2.pm_type.value)
					if dt in [PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]:
						return SGlobal.basictypes[PrimitiveType.INT]
					return SGlobal.basictypes[dt]
				raise WAFCompileError(1013, None)
			elif o in [OprShift.LEFT_SHIFT,OprShift.RIGHT_SHIFT,OprShift.RIGHT_RIGHT_SHIFT]:

				if (not SA.isBasicNumericType(t1)) or ( not SA.isBasicNumericType(t2)):
					raise WAFCompileError(1013, None)
				dt1=t1.pm_type.value
				dt2=t2.pm_type.value
				if dt1 in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
					raise "Shift can not be applied on float or double"
				if dt2 in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
					raise "Shift can not be applied on float or double"
				dt=dt1#NOTE:int shift left operand is important
				if dt in [PrimitiveType.BYTE,PrimitiveType.CHAR,PrimitiveType.SHORT]:
					return SGlobal.basictypes[PrimitiveType.INT]
				return SGlobal.basictypes[dt]
			elif o == OprInstanceOf.INSTANCEOF:
				#TODO:reducet this
				return SGlobal.basictypes[PrimitiveType.BOOLEAN]
				
			elif o in [ OprEquality.ET, OprEquality.NET, OprLogical.AND, OprLogical.OR, OprRelational.GT, OprRelational.GTE, OprRelational.LT, OprRelational.LTE]:
				
				return SGlobal.basictypes[PrimitiveType.BOOLEAN]
			elif o in [ OprAssign.NORMAL, OprAssign.PLUS,OprAssign.MINUS,OprAssign.MULTIPLY,OprAssign.DIVIDE,OprAssign.MOD,OprAssign.AND,OprAssign.XOR,OprAssign.OR,OprAssign.LEFT_SHIFT,OprAssign.RIGHT_SHIFT,OprAssign.RIGHT_RIGHT_SHIFT]:
				if o==OprAssign.NORMAL or o==OprAssign.PLUS:
					if SHelper.matchType(t1, t2):
						return t1
					if o==OprAssign.NORMAL:
						_t2=SA.getTypeIfConstant(p[2])
						if _t2!=None:
							t2=_t2					
					if SA.isBasicType(t1) and SA.isBasicType(t2):
						d=SHelper.matchTypeAndGetDegree(t2, t1)
						if d==-1:
							d=SHelper.matchTypeAndGetDegree(t2, t1)
							raise WAFCompileError(1013, None)
						return t1
					elif SA.isBasicType(t1) or SA.isBasicType(t2):
						if SA.isBasicType(t1):
							#unboxing
							u_t2=SA.fromWrapperClassToBasic(t2)
							d=SHelper.matchTypeAndGetDegree(u_t2,t1)
							if d==-1:
								raise WAFCompileError(1013, None)
							return t1
						else:
							b_t2=SA.fromBasicToWrapperClass(t2)
							d=SHelper.matchTypeAndGetDegree(b_t2,t1)
							if d==-1:
								raise WAFCompileError(1013, None)
							return SA.fromWrapperClassToBasic(t1)
					else:#both are object
						
						d=SHelper.matchTypeAndGetDegree(t2,t1)
						if d!=-1:
							return t1	
						if SA.isWrapperClass(t1) and SA.isWrapperClass(t2):
							u_t1=SA.fromWrapperClassToBasic(t1)
							u_t2=SA.fromWrapperClassToBasic(t2)
							d=SHelper.matchTypeAndGetDegree(u_t2, u_t1)
							if d!=-1:
								return t1
						raise WAFCompileError(1013, None)
				if (not SA.isBasicNumericType(t1)) or ( not SA.isBasicNumericType(t2)):
					raise WAFCompileError(1013, None)
				dt1=t1.pm_type.value
				dt2=t2.pm_type.value
				if o==OprAssign.NORMAL:
					#Type casting here
					return SGlobal.basictypes[dt1] 
				elif o in [OprAssign.PLUS,OprAssign.MINUS,OprAssign.MULTIPLY,OprAssign.DIVIDE,OprAssign.MOD]:
					return SGlobal.basictypes[dt1]
				elif o in [OprAssign.AND ,OprAssign.OR,OprAssign.XOR,OprAssign.LEFT_SHIFT,OprAssign.RIGHT_SHIFT,OprAssign.RIGHT_RIGHT_SHIFT]:
					if dt1 in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
						raise "Shift can not be applied on float or double"
					if dt2 in [PrimitiveType.FLOAT,PrimitiveType.DOUBLE]:
						raise "Shift can not be applied on float or double"
					return SGlobal.basictypes[dt1]
				else:some_method()
			elif o in [OprTernary.IF,OprTernary.ELSE]:
				if o==OprTernary.IF:
					if not SA.isBasicType(t1):raise "Expecting boolean in ternary operator"
					dt1=t1.pm_type.value
					if dt1!=PrimitiveType.BOOLEAN:raise "Expecting boolean in ternary operator"
					return t2;
				else:
					if SA.isBasicType(t1) and SA.isBasicType(t2):						
						dt1=t1.pm_type.value
						dt2=t2.pm_type.value
						if SA.isBasicNumericType(t1) and SA.isBasicNumericType(t2):
							dt=max(dt1,dt2)
							return SGlobal.basictypes[dt]
						elif dt1==PrimitiveType.BOOLEAN and dt2==PrimitiveType.BOOLEAN:
							return t1
						else:
							raise "Uncompatible datatype in ternary else"
					elif SA.isBasicType(t1) or SA.isBasicType(t2):
						#one of them is basic , and one is object
						if SA.isBasicType(t1):
							if SA.canUnbox(t2):
								ub_t2=SA.fromWrapperClassToBasic(t2)#unboxed
								dt1=t1.pm_type.value
								dt2=ub_t2.pm_type.value
								return SGlobal.basictypes[max(dt1,dt2)]
							else:
								#This mean we have to box the basic type
								b_t1=SA.fromBasicToWrapperClass(t1)
								clz2=SA.getClassForType(t2)
								d1=b_t1.coit.clazz.getDegreeWithThis(clz2)
								d2=clz2.getDegreeWithThis(b_t1.coit.clazz)
								if d1!=-1 and d2!=-1:
									#TODO:this is modtly possible ternary else returngin same object
									if d1>d2:
										return b_t1
									else:
										return t2
								elif d1!=-1 or d2!=-1:
									if d1!=-1:
										return t2
									else:
										return b_t1
								else:
									#wrap t1
									return SGlobal.objclass.mytype 
						else:
							#t1 is object
							if SA.canUnbox(t1):
								ub_t1=SA.fromWrapperClassToBasic(t1)#unboxed
								dt1=t2.pm_type.value
								dt1=ub_t1.pm_type.value
								return SGlobal.basictypes[max(dt1,dt2)]
							else:
								#This mean we have to box the basic type
								b_t2=SA.fromBasicToWrapperClass(t2)
								clz1=SA.getClassForType(t1)
								d1=b_t2.coit.clazz.getDegreeWithThis(clz1)
								d2=clz1.getDegreeWithThis(b_t2.coit.clazz)
								if d1!=-1 and d2!=-1:
									#TODO:this is modtly possible ternary else returngin same object
									if d1>d2:
										return b_t2
									else:
										return t1
								elif d1!=-1 or d2!=-1:
									if d1!=-1:
										return t1
									else:
										return b_t2
								else:
									#wrap t1
									return SGlobal.objclass.mytype 
					else:
						clz1=SA.getClassForType(t1)
						clz2=SA.getClassForType(t2)
						d1=clz1.getDegreeWithThis(clz2)
						d2=clz2.getDegreeWithThis(clz1)
						if d1!=-1 and d2!=-1:
							#TODO:this is modtly possible ternary else returngin same object
							if d1>d2:
								return t2
							else:
								return t1
						elif d1!=-1 or d2!=-1:
							if d1!=-1:
								return t1
							else:
								return t2
						else:
							#wrap t1
							return SGlobal.objclass.mytype
				some_method()
			else:
				return t1
			#TODO:need to do lots of checking skipping for time being
			#if o>=OprAssign.NORMAL and o<=OprAssign.RIGHT_RIGHT_SHIFT:
		else:
			raise WAFCompileError(-1, "Unkwon combination for tuple 493")
	@staticmethod
	def getTypeIfConstant(p):
		if not( isinstance(p,list) and len(p)==1) :return None
		p=p[0]
		if isinstance(p, ExLiteral):
			return SGlobal.getBasicTypeForLiteral2(p.literal)
		elif isinstance(p, ExPrimary):
			return SA.getTypeIfConstant(p.parts)		
		return None
		
	@staticmethod
	def checkExpressionTupleArray(parts, sym, si):
		#sanity check
		if len(parts)==1:
			return SA.checkExpressionArray(parts[0],sym,si)
		if not(isinstance(parts[0],ExOperator) or isinstance(parts[1],ExOperator)):
			some_method()
		count=len(parts)
		#o1=ExOperator()
		#o2=ExOperator()
		i=0
		stack=[]
		out=[]
		p=parts		
		while i<count:
			if isinstance(p[i],ExOperator):
				o1=p[i]
				while len(stack)>0 and isinstance(stack[len(stack)-1],ExOperator):
					o2=stack[len(stack)-1]
					if o1.isLeftToRight() and o1.getPrecedance()>=o2.getPrecedance():
						out.append(stack.pop())
					elif o1.isRightToLeft() and o1.getPrecedance()>o2.getPrecedance():
						out.append(stack.pop())
					else:
						break
				stack.append(o1)
				i+=1			
			else:
				out.append(p[i])
				i+=1
		while len(stack)>0:
			out.append(stack.pop())
		
		
		count=len(out)
		out2=[]
		for i in range(count):
			out2.append(out[count-i-1])
		tc=[0] 
		r=SA.getResolvedExpression(out2,tc)
		if tc[0]!=count:
			print tc[0]
			print count
			some_method()
		return SA.checkExpressionTuple(r, sym, si)
			
	@staticmethod
	def getResolvedExpression(a,consumed):
		count=len(a)
		if count==0:
			raise "Error" 
		o=a[0]
		tor=[]
		if not isinstance(o,ExOperator):
			tor.append(o)
			consumed[0]=1
			return tor
		if o.value in [OprPostfix.DEC,OprPostfix.INC]:
			tc=[0]
			r=SA.getResolvedExpression(a[1:],tc)
			consumed[0]=1+tc[0]
			tor.append(r)
			tor.append(o)
			return tor
		elif o.value in [OprUnary.INC,OprUnary.DEC,OprUnary.NEGATIVE,OprUnary.NOT,OprUnary.POSITIVE,OprUnary.TILDE]:
			tc=[0]
			r=SA.getResolvedExpression(a[1:],tc)
			consumed[0]=1+tc[0]
			tor.append(o)
			tor.append(r)
			return tor
		else:
			tc=[0]
			r=SA.getResolvedExpression(a[1:],tc)
			consumed[0]=1+tc[0]
			tor.append(r)
			tor.append(o)
			tc=[0]
			r=SA.getResolvedExpression(a[consumed[0]:],tc)
			consumed[0]+=tc[0]
			tor.append(r)
			return tor
		
	@staticmethod
	def getTypeWithReducedArray(t):
		return t.coit.next
	@staticmethod
	def ttos(p):
		if type(p).__name__ == 'instance':
			return p.__class__.__name__
		else:
			return  type(p).__name__
	@staticmethod
	def toSParts(parts):
		s = ""
		for p in parts:
			if type(p).__name__ == 'instance':
				s += " " + p.__class__.__name__
				if isinstance(p, ExIdentifier):
					s += "(" + p.name.data + ")"
			else:
				s += "{ " + SA.toSParts(p) + " }"
		return s
	@staticmethod
	def getFieldFromCurrentClass(name, static_only=False):
		cls = SA.currentClass
		f = cls.getFieldWithThisAccess(name, static_only, cls)
		return f
	@staticmethod
	def getFieldFromContainerClass(name, static_only=False):
		cls = SA.currentClass
		f = cls.getFieldFromContainerClass(name, static_only, cls)
		return f	
	@staticmethod
	def getMethodFromContainerClass(name, args, static_only=False):
		cls = SA.currentClass
		m = SClass.getMethodFromContainerClass(name, args, static_only, cls)
		#f=cls.getFieldWithThisAccess(name,only_static,SA.currentClass)
		return m

	@staticmethod
	def checkExpressionArray(parts, sym, i):
		if isinstance(parts, ExType):
			SHelper.processType(parts.typ, SA.currentClass, SA.currentMethod)
			return parts.typ
		if not isinstance(parts, list):
			print "what is this"
			some_method()
		#print "Parts " + SA.toSParts(parts)
		if SA.isExpressionTuple(parts):
			return SA.checkExpressionTuple(parts, sym, i)
		pcount = len(parts)
		for pi in range(0, pcount):
			p = parts[pi]
			if isinstance(p, ExPrimary):
				r = SA.checkExpressionArray(p.parts, sym, i)
				if pi + 1 == pcount:return r
				np = parts[pi + 1]
				if isinstance(np, ExDot):
					return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
				##########
				if isinstance(np, ExArrayIndex):
					if r.coit == None or r.coit.clazz != SGlobal.arrayclass:
						raise WAFCompileError(-1, "Not an array")
					t = SA.checkExpression(np.exp, sym, i)
					if isinstance(t, Type):
						if not SA.canBeArrayIndex(t):
							raise WAFCompileError("Can not evalute to positive integer")
					if pi + 2 == pcount:return SA.getTypeWithReducedArray(r)
					np=parts[pi+2]
					r=SA.getTypeWithReducedArray(r)
					if isinstance(np,ExDot):
						return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i)
					if isinstance(np,ExArrayIndex):
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
				##########
				raise WAFCompileError(-1, "Primary Error 535")
				#TODO:handle postfix operators ++,--

			elif isinstance(p, list):
				if SA.isExpressionTuple(p):
					return SA.checkExpressionTuple(p, sym, i)
				else:
					return SA.checkExpressionTupleArray(parts, sym, i)
			elif isinstance(p, ExThis):
				if pi + 1 == pcount:
					return SA.currentClass.mytype
				np = parts[pi + 1]
				#this()
				if isinstance(np, ExArguments):#calling another constructor
					argstl = SA.getExpressionListToTypeList(np.arguments, sym, i)
					_argstl = []
					for _arg in argstl: 
						_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg,None,SA.currentMethod))
					argstl = _argstl
					mc=SA.currentClass.getConstructor(argstl, SA.currentClass)
					if mc==None:
						raise WAFCompileError(1007, SA.currentClass.name)
					if WAFConfig.isRemoveUnusedCode():
						SA.addMethodRef(mc.mid)
					pi = pi + 1
					return None
				#this.member....
				elif isinstance(np, ExDot):
					#TODO:Method parameters possible here
					pi = pi + 2
					p = parts[pi]
					if pi + 1 == pcount:
						f = SA.currentClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						if WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(f.field.mid)
						return SA.currentClass.mytype.mapAndConvertType(f.type,None,SA.currentMethod)
					np = parts[pi + 1]
					if isinstance(np, ExDot):
						f = SA.currentClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						if WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(f.field.mid)
						r = SA.currentClass.mytype.mapAndConvertType(f.type,None,SA.currentMethod)
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
					elif isinstance(np, ExArguments):
						args = np.arguments
						argstl = SA.getExpressionListToTypeList(args, sym, i)
						_argstl = []
						for _arg in argstl: 
							_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg,None,SA.currentMethod))
						argstl = _argstl

						#access_control=SA.getAccessControl(SA.currentClass,SA.currentClass)
						m = SA.currentClass.mytype.getMethodWithThisAccess(p.name.data, argstl, False,None, SA.currentClass)
						
						#m = SA.currentClass.getMethodPrivateAccess(p.name.data, argstl, 0)
						if m == None:
							raise WAFCompileError(1009, p.name.data)
						if m.method.calls_model==True:
							SA.calls_model=True
						if WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(m.method.mid)
						if m.method.is_void:return None
						r = SA.currentClass.mytype.mapAndConvertType(m.rtype,None,SA.currentMethod)
						if pi + 2 == pcount:return r
						if isinstance(parts[pi + 2], ExDot):							
							return SA.checkDotDotExpression(r, parts, pi + 3, pcount, None, sym, i)
						if isinstance(parts[pi + 2], ExArrayIndex):							
							return SA.checkDotDotExpression(r, parts, pi + 2, pcount, None, sym, i)
						raise WAFCompileError(0, "what is this in method")
				else:
					raise WAFCompileError(-1, "What the hell is this")
			elif isinstance(p, ExIdentifier):
				name = p.name.data;
				if pi + 1 == pcount:
					t = SA.getVariable(name, sym, i)			
					if t == None:
						t = SA.getFieldFromCurrentClass(name)#update this for static members
						if t!=None and WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(t.field.mid)					
					if t == None:
						t = SA.getFieldFromContainerClass(name)
						if t!=None and WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(t.field.mid)
					if t == None:
						t = SA.getFieldFromContainerClass(name)
						print name, p.name.lineno, p.name.pos
						raise WAFCompileError(1009, p.name)
					if  SA.isDeclaration(t):return t
					
					return SA.currentClass.mapAndConvertType(SA.getTypeOfVariable(t), None, SA.currentClass,None,SA.currentMethod)#TODO:this is wrong i guess
				np = parts[pi + 1]
				if isinstance(np, ExDot) or isinstance(np, ExArrayIndex):
					t = SA.getVariable(name, sym, i)
					if t != None and isinstance(t, SPackage):
						npi = pi + 1
						pack_str = t.name 
						while  npi + 1 < pcount and isinstance(parts[npi], ExDot) and  isinstance(parts[npi + 1], ExIdentifier):
							p = parts[npi + 1]
							t = SA.getVariable(pack_str + "." + p.name.data, sym, i)
							npi += 2
							if isinstance(t, SPackage):
								pack_str += "." + p.name.data
							elif isinstance(t, STypeDeclaration):
								pack_str += "." + p.name.data
								break
							else:
								print t, pack_str + "." + p.name.data
								print "Error", some_method()
						if not isinstance(t, STypeDeclaration):
							print "Type not found", pack_str
							some_method()
						if npi + 1 == pcount:return t
						np = parts[npi]
						if not isinstance(np, ExDot):
							print "Expecting dot(.)", some_method()
						npi = npi + 1
						if npi + 1 > pcount :
							print "Unexpected ", some_method()#TODO:ERROR REPORT
						np = parts[npi]
						if isinstance(np, ExThis):
							if npi + 1 == pcount:
								return t.mytype
							else:
								return SA.checkDotDotExpression(t.mytype, parts, npi + 1, pcount, sym, i)
						else:
							return SA.checkDotDotExpression(t, parts, npi , pcount, sym, i)
							
							
								
							#depth goes her in java2js
							
							
						
					if t == None:
						t = SA.getFieldFromCurrentClass(name)#update this for static members
						if t!=None and WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(t.field.mid)
					if t == None:
						t = SA.getFieldFromContainerClass(name)
						if t!=None and WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(t.field.mid)
					if t == None:
						print name
						raise WAFCompileError(1009, p.name)
					if SA.isDeclaration(t):
						return SA.checkDotDotExpression(t, parts, pi + 2, pcount, sym, i)
					vtype = SA.currentClass.mapAndConvertType(SA.getTypeOfVariable(t), None, SA.currentClass,None,SA.currentMethod)
					if isinstance(np, ExDot):
						if vtype.coit != None:#coit type
							return SA.checkDotDotExpression(vtype, parts, pi + 2, pcount, sym, i)
						print "VN", name, SA.ttos(np)
						raise WAFCompileError(-1, "Expecting class,interface , enum ,obejct")
					elif isinstance(np, ExArrayIndex):
						if vtype.coit == None or vtype.coit.clazz != SGlobal.arrayclass:
							raise WAFCompileError(-1, "Not an array")
						t = SA.checkExpression(np.exp, sym, i)
						if isinstance(t, Type):
							if not SA.canBeArrayIndex(t):
								raise WAFCompileError("Can not evalute to positive integer")
						else:
							raise WAFCompileError("Can not evalute to positive integer")
						r = SA.getTypeWithReducedArray(vtype)
						#r=SA.mapTypeToTypeArgument(_typeargs, r)
						if pi + 2 == pcount:return r
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
					else:
						print "UnExpected"
						sys.exit()
				elif isinstance(np, ExArguments):
					curClass = SA.currentClass
					argstl = SA.getExpressionListToTypeList(np.arguments, sym, i)
					#access_control=SA.getAccessControl(SA.currentClass,curClass)
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curClass.mytype.mapAndConvertType(_arg,None,SA.currentMethod))
					argstl = _argstl
					m = curClass.mytype.getMethodWithThisAccess(name, argstl, False,None, SA.currentClass)
					
					if m == None:
						m = curClass.getMethodFromContainerClass(name, argstl, False, SA.currentClass)					
					if m == None:
						m = curClass.getMethodWithThisAccess(name, argstl, False,None, SA.currentClass)
						if m == None:
							m = curClass.getMethodFromContainerClass(name, argstl, False, SA.currentClass)
						print p.name.lineno, p.name.pos
						print "SA ", SA.currentClass.fullname
						print "curClass", curClass.fullname, curClass.exclass[0].fullname, name
						raise WAFCompileError(1009, p.name)
					if m.method.calls_model==True:
						SA.calls_model=True
					if WAFConfig.isRemoveUnusedCode():
						SA.addMethodRef(m.method.mid)
					if m.method.is_void == True:return None
					rtype = curClass.mytype.mapAndConvertType(m.rtype,None,SA.currentMethod)
					#rtype=SA.mapTypeToTypeArgument(_typeargs, type)
					if pi + 2 == pcount:return rtype
					return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i)
				elif isinstance(np, ExInnerCreator):
					curClass = SA.currentClass
					t = SA.getVariable(name, sym, i)
					creator = np.creator
					if t == None:
						t = SA.getFieldFromCurrentClass(name)#update this for static members
						if t!=None and WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(t.field.mid)
					if t == None:
						t = SA.getFieldFromContainerClass(name)
						if t!=None and WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(t.field.mid)
					outerClass = SA.getTypeOfVariable(t).coit.clazz
					innerClass = outerClass.getInnerMember(creator.name.data)
					argstl = SA.getExpressionListToTypeList(creator.classcreator.args, sym, i)		
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curClass.mytype.mapAndConvertType(_arg,None,SA.currentMethod))
					argstl = _argstl
					cons = innerClass.getConstructor(argstl, SA.currentClass)
					if cons == None:
						print "Constructor not found for inner class"
						print innerClass.getFullname()
						print outerClass.getFullname()
						some_method()
					if WAFConfig.isRemoveUnusedCode():
						SA.addMethodRef(cons.mid)
					return innerClass.mytype
					
				else:
					print np
					raise WAFCompileError(-1, "unknown combination")
			elif isinstance(p, ExCastExpression):
				#TODO:it me array be carefull not handled right now
				#TODO:check compile time for possible casting of this
				t = SA.checkExpressionArray(p.exp, sym, i)
				if isinstance(p.typ, PrimitiveType):
					return SGlobal.getBasicTypeForPrimitiveType(p.typ)
				else:
					SHelper.processType(p.typ, SA.currentClass, SA.currentMethod)
					return SA.currentClass.mytype.mapAndConvertType(p.typ,None,SA.currentMethod)
			elif isinstance(p, ExCreator):
				## class creator
				c = p.creator
				if c.arraycreator == None:
					return SA.processClassCreator(c, sym, i)
				else:
					return SA.processArrayCreator(c.arraycreator, sym, i)
			elif isinstance(p, ExLiteral):
				return SA.checkLiteral(p.literal, sym, i)
			elif isinstance(p, ExParExpression):
				return SA.checkExpression(p.exp, sym, i)
			elif isinstance(p, ExPrimitiveType):
				#TODO:verify this currently ignoring
				return SGlobal.getBasicTypeForPrimitiveType(p)
			elif isinstance(p, ExSuper):
				if len(SA.currentClass.exclass) == 0:
					raise WAFCompileError("Class dosent have super class")

				supClass = SA.currentClass.exclass[0]
				if pi + 1 == pcount:
					raise WAFCompileError("Unexpected use of super")
				np = parts[pi + 1]
				if isinstance(np, ExArguments):#calling super constructor
					mc=supClass.getConstructor(SA.getExpressionListToTypeList(np.arguments, sym, i), SA.currentClass)
					if mc==None:
						raise WAFCompileError(1007, None)
					if WAFConfig.isRemoveUnusedCode():
						SA.addMethodRef(mc.mid)
					pi = pi + 1
				#this.member....
				elif isinstance(np, ExDot):
					#TODO:method parameters here
					pi = pi + 2
					p = parts[pi]
					if pi + 1 == pcount:
						f = supClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						if WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(f.field.mid)
						return SA.currentClass.mytype.mapAndConvertType(f.type,None,SA.currentMethod)
					np = parts[pi + 1]
					if isinstance(np, ExDot):
						f = supClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						if WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(f.field.mid)
						r = SA.currentClass.mytype.mapAndConvertType(f.type,None,SA.currentMethod)
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, None, sym, i)
					elif isinstance(np, ExArguments):
						args = np.arguments
						argstl = SA.getExpressionListToTypeList(args, sym, i)
						#access_control=SA.getAccessControl(SA.currentClass,SA.currentClass)
						_argstl = []
						for _arg in argstl: 
							_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg,None,SA.currentMethod))
						argstl = _argstl
						m = supClass.getMethodWithThisAccess(p.name.data, argstl, False,None, SA.currentClass)

						#m = SA.currentClass.getMethodPrivateAccess(p.name.data, argstl, 0)
						if m == None:
							raise WAFCompileError(1009, p.name.data)
						if WAFConfig.isRemoveUnusedCode():
							SA.addMethodRef(m.method.mid)
						if m.method.is_void:return None
						r = SA.currentClass.mytype.mapAndConvertType(m.rtype,None,SA.currentMethod)
						if pi + 2 == pcount:return r
						if isinstance(parts[pi + 2], ExDot):
							return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i)
						if isinstance(parts[pi + 2], ExArrayIndex):
							return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i)
						raise WAFCompileError(0, "what is this in method")
				else:
					raise WAFCompileError(-1, "What the hell is this")
				#TODO:
				print "Super not supported"
				some_method()
				#sys.exit(0)
			elif isinstance(p, ExType):
				#TODO:this should be after the intanceof
				pass
			elif isinstance(p, ExTypeArguments):
				#TODO:ideally this should be ignored just verify it
				pass
			elif isinstance(p, ExVoid):
				#TODO:ideally never be used in code which is goind to be translated to javascript
				pass
			else:
				print "Unknown Expression part ", p
				some_method()
			pi += 1
		return None#TODO:could be error
	@staticmethod
	def processArrayCreator(ac, sym, i):
		#TODO:process array creator init
		if ac.exps != None:			
			for e in ac.exps:
				SA.checkExpression(e, sym, i)
		t = Type()
		t.arraydim = ac.arraydim

		if isinstance(ac.name, ClassOrInterfaceType):
			t.coit = ac.name
		else:
			t.pm_type = ac.name
		SHelper.processType(t, SA.currentClass, SA.currentMethod)
		return t
	
	@staticmethod
	def processClassCreator(c, sym, i):
	
		cls = SA.currentClass
	
		name = SHelper.getCoitNamesToString(c.typ)
		if name == None:
			name = c.typ.fullname
		currentType = Type()
		currentType.coit = c.typ
		SHelper.processType(currentType, SA.currentClass, SA.currentMethod)
		oclass = SHelper.getClassOnNameFromImported(name, SA.currentClass)
		if oclass == None:
			oclass = SHelper.getClassOnNameFromImported(name, SA.currentClass)
			print name
			raise WAFCompileError(1015, c.typ.names[0])#TODO:check this names[0]
		
		bclass = SClass()
		c.clazz = bclass
		bclass.setFullname(oclass.getFullname())
		bclass.setPackage(cls.getPackage())
		bclass.setInner(True)
		bclass.setModifiers(oclass.getModifiers())
		bclass.setCompilationUnit(cls.getCompilationUnit())
		mt = Type()
		mt.coit = ClassOrInterfaceType()
		mt.coit.fullname = oclass.fullname
		mt.coit.clazz = bclass
		bclass.setMyType(mt)
		if oclass.isClass():
			#bclass.exclass.append(oclass)
			bclass.extends.append(currentType)
		else:
			#bclass.implclass.append(oclass)
			bclass.implements.append(currentType)
			
		#oclass = oclass.getCopy(SA.currentClass)
		ccr = c.ccr
		argstl = SA.getExpressionListToTypeList(ccr.args, sym, i)
		_argstl = []
		for _arg in argstl: 
			_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg,None,SA.currentMethod))
		argstl = _argstl
		if oclass.isClass():# and (not oclass.isAbstract()):
			cons = oclass.getConstructor(argstl, SA.currentClass)
			if cons == None:
				if (not oclass.isClass()):
					raise WAFCompileError(1007, c.typ.names[0])#TODO:check this names[0]
			if cons!=None and WAFConfig.isRemoveUnusedCode():
				SA.addMethodRef(cons.mid)
			
		if SA.currentMethod!=None:
			bclass.declclazz = SA.currentMethod
		else:
			bclass.declclazz = SA.currentClass
		if c.ccr.body == None:
			return oclass.mytype
		for m in ccr.body:
			if isinstance(m, Field):
				fields = SHelper.readFields(m)
				for f in fields:
					f.setDeclaringClass(bclass)
					bclass.addField(f)
			elif isinstance(m, Method):
				m = SHelper.readMethod(m)
				m.setDeclaringClass(bclass)
				bclass.addMethod(m)
				tpars = m.typepars
				if tpars != None:
					index = 0
					for tp in tpars:
						name = tp.name.data
						SHelper.processTypeParameter(tp, bclass)
						tp.index = index
						tp.forclass = None
						tp.formethod = m
						index += 1

				if m.rettype != None:
					SHelper.processType(m.rettype, bclass, m)
				for p in m.pars:
					SHelper.processType(p.typ, bclass, m)
			else:
				print m
				print "INCOMPLETE_COMPILATION:Inner member not processed"
				some_method()
		bclass.removeModifier(SModifier.ABSTRACT)
		SHelper.processSClass(bclass)
		SA.currentClasses.append(SA.currentClass)
		SA.checkSClass(bclass, sym, i)
		SA.currentClass = SA.currentClasses.pop()
		return bclass.mytype


	@staticmethod
	def getVariable(name, sym, i):
		while i >= 0:
			if sym[i].has_key(name):
				return sym[i][name]
			i -= 1
		if SHelper.isEndsWith(SA.currentClass.fullname, name):
			return SA.currentClass
		cls = SHelper.getClassOnNameFromImported(name, SA.currentClass)
		if cls != None:
			return cls
		return None
		#print name
		#raise WAFCompileError(-1, "Identifier not found")
	@staticmethod
	def getTypeOfVariable(v):
		if isinstance(v, Type):
			return v
		if isinstance(v, Parameter):
			return SA.getTypeOfVariable(v.typ)
		if isinstance(v,ExField):
			return SA.getTypeOfVariable(v.type)
		if isinstance(v, SField):
			return SA.getTypeOfVariable(v.type)
		if isinstance(v, SClass):
			return v.mytype
		if isinstance(v, SInterface):
			return v.mytype
		if isinstance(v, VariableDeclarator):
			return SA.getTypeOfVariable(v.typ)
		if isinstance(v, TypeParameter):
			if v.bound != None:
				return SA.getTypeOfVariable(v.bound[0])
			return SGlobal.objclass.mytype
			
		print SA.ttos(v)
		raise WAFCompileError(-1, "invalid argument passed to ge the type")

	@staticmethod
	def checkLiteral(l, sym, i):#TODO
		return SGlobal.getBasicTypeForLiteral(l)

	@staticmethod
	def checkOperator(o, sym, i):#complete
		if o >= OprAssign.NORMAL and o <= OprAssign.RIGHT_RIGHT_SHIFT:
			if o == OprAssign.AND:			return "&="
			if o == OprAssign.DIVIDE:		 return  "/="
			if o == OprAssign.LEFT_SHIFT:		 return  "<<="
			if o == OprAssign.MINUS:		  return  "-="
			if o == OprAssign.MOD:			return  "%="
			if o == OprAssign.MULTIPLY:		   return  "*="
			if o == OprAssign.NORMAL:		 return  "="
			if o == OprAssign.OR:			 return  "|="
			if o == OprAssign.PLUS:		   return  "+="
			if o == OprAssign.RIGHT_RIGHT_SHIFT:	  return  ">>>="
			if o == OprAssign.RIGHT_SHIFT:		return  ">>="
			if o == OprAssign.XOR:			return  "^="
		if o >= OprBinary.AND and o <= OprBinary.XOR:
			if o == OprBinary.AND:	return "&"
			if o == OprBinary.OR:	 return "|"
			if o == OprBinary.XOR:	return "^"
		if o >= OprLogical.AND and o <= OprLogical.OR:
			if o == OprLogical.AND:   return "&&"
			if o == OprLogical.OR:	return "||"
		if o >= OprRelational.GT and o <= OprRelational.LTE:
			if o == OprRelational.GT: return ">"
			if o == OprRelational.GTE:return ">="
			if o == OprRelational.LT: return "<"
			if o == OprRelational.LTE:return "<="
		if o >= OprEquality.ET and o <= OprEquality.NET:
			if o == OprEquality.ET:   return "=="
			if o == OprEquality.NET:  return "!="
		if o >= OprShift.LEFT_SHIFT and o <= OprShift.RIGHT_RIGHT_SHIFT:
			if o == OprShift.LEFT_SHIFT:	  return "<<"
			if o == OprShift.RIGHT_SHIFT:	 return ">>"
			if o == OprShift.RIGHT_RIGHT_SHIFT:return ">>>"
		if o >= OprTernary.IF and o <= OprTernary.ELSE:
			if o == OprTernary.IF:	return "?"
			if o == OprTernary.ELSE:  return ":"
		if o >= OprAdditive.PLUS and o <= OprAdditive.MINUS:
			if o == OprAdditive.PLUS: return "+"
			if o == OprAdditive.MINUS:return "-"
		if o >= OprMultiplicative.MULTIPY and o <= OprMultiplicative.MOD:
			if o == OprMultiplicative.DIVIDE: return "/"
			if o == OprMultiplicative.MOD:	return "%"
			if o == OprMultiplicative.MULTIPY:return "*"
		if o >= OprUnary.INC and o <= OprUnary.TILDE:
			if o == OprUnary.DEC:return "--"
			if o == OprUnary.INC:return "++"
			if o == OprUnary.NEGATIVE:return "-"
			if o == OprUnary.NOT:return "!"
			if o == OprUnary.TILDE:return "~"
			if o == OprUnary.POSITIVE:return "+"
		if o >= OprPostfix.INC and o <= OprPostfix.DEC:
			if o == OprPostfix.INC:return "++"
			if o == OprPostfix.DEC:return "--"
		if o == OprInstanceOf.INSTANCEOF:
			return " instanceof "#spaces are necessory here
		raise Exception("Fatal Error: could not found operator")


